﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Un4seen.Bass;
using sdd.subsystems.audio;
using sdd.subsystems.io;
using sdd.subsystems.display;
using sdd.subsystems.memory;
using sdd.subsystems.ui;
using sdd.subsystems.ui.screens;
using sdd.subsystems.config;
using sdd.apps;

// SIRP Experimental Firmware
// Abstracts the Software Defined Device
// (c) 2014 Chris Burri. MIT License applies. 
// See http://niston.wordpress.com

namespace sdd
{
    public class Director
    {

        #region Member Vars
        // device serial port
        private SerialIOComPort _SerialPort;

        private ApplicationManager _AppManager;
        
        
        private SwitchMenuItem testItem = new SwitchMenuItem("Topmost LED (green)", false);

        #endregion

        #region Constructor/Destructor
        public Director()
        {
            if (IsRunningOnMono)
            {
                _SerialPort = new SerialIOComPort("/dev/ttyUSB0");
            }
            else
            {
                _SerialPort = new SerialIOComPort("COM8");
            }
            _SerialPort.Open();

            Display = new DisplayMxoGlk(_SerialPort);
            Display.SetLedIndicators(LedLocations.Top, LedColors.Dark, true);
            Display.SetLedIndicators(LedLocations.Middle, LedColors.Dark, true);
            Display.SetLedIndicators(LedLocations.Bottom, LedColors.Dark, true);

            // create screen manager and menu system
            ScreenManager = new ScreenManager(this, Display);

            // add top level menus
            ScreenManager.Menus.Register(new MenuItem("Application"));
            ScreenManager.Menus.Register(new MenuItem("Audio"));
            ScreenManager.Menus.Register(new MenuItem("Network"));
            ScreenManager.Menus.Register(new MenuItem("System"));
            ScreenManager.Menus.Register(new MenuItem("Test"));

            ScreenManager.Menus.Menu("Test").SubItems.Add(new IntMenuItem("Test Int (0-100)", 0, 0, 100));
            ScreenManager.Menus.Register(testItem, ScreenManager.Menus.Menu("Test"));
            testItem.ValueChanged += testItem_ItemChanged;

            _AppManager = new ApplicationManager();
            _AppManager.Director = this;

            // register screens
            ScreenManager.Register(new ScrMenuMain());
            ScreenManager.Register(new ScrClock());
            ScreenManager.Register(new ScrNetworkSetup());
        }

        ~Director()
        {
            
            testItem.ValueChanged -= testItem_ItemChanged;

            _AppManager.UnloadAll();
            _AppManager.Director = null;
            _AppManager = null;

            ScreenManager = null;

            Display = null;

            _SerialPort.Close();
            _SerialPort = null;
        }
        #endregion

        #region Public Interface

        // the Display
        public IDisplay Display { private set; get; }

        // the Screen Manager
        public ScreenManager ScreenManager { private set; get; }

        //  Check if port available on Linux: File.Exists(s.PortName);
        public bool IsRunningOnMono { get { return (Type.GetType("Mono.Runtime") != null); } }

        // initialize director and subsystems
        public void Initialize()
        {
            DynConfigurator cfgLoader = new DynConfigurator();
            cfgLoader.LoadConfigurator("test.conf");
            _AppManager.Load("StreamOne", "AppTuner");
            _AppManager.Application("Tuner").Activate();
        }

        #endregion
        
        #region Private Methods
        void testItem_ItemChanged(object sender, ObservableMenuItemValueChangedEventArgs<bool> e)
        {
            // react to BoolMenuItem change
            Display.SetLedIndicators(LedLocations.Top, (e.NewValue ? LedColors.Green : LedColors.Dark));
        }
        #endregion

    }
}
